package com.example.common.application;

import com.example.common.constant.LauncherConstant;
import lombok.NoArgsConstructor;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.*;
import org.springframework.util.StringUtils;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import java.util.function.Function;

/**
 * @author benjamin_5
 * @Description
 * @date 2023/3/31
 */
@EnableDiscoveryClient
@EnableAutoConfiguration
@NoArgsConstructor
public class SpringSelfApplication {

    public static ConfigurableApplicationContext run(String applicationName, Class source, String ...args){
        SpringApplicationBuilder builder = createBuilder(applicationName, source, args);
        return builder.run(args);
    }

    public static SpringApplicationBuilder createBuilder(String appName, Class source, String ...args){
        // 获取环境profile
        ConfigurableEnvironment environment = new StandardEnvironment();
        // 加载其他环境变量，比如从命令行输入的环境环境变量
        MutablePropertySources propertySources = environment.getPropertySources();
        propertySources.addFirst(new SimpleCommandLinePropertySource(args));
        propertySources.addLast(new MapPropertySource("systemProperties", environment.getSystemProperties()));
        propertySources.addLast(new SystemEnvironmentPropertySource("systemEnvironment", environment.getSystemEnvironment()));
        String[] activeProfiles = environment.getActiveProfiles();
        List<String> profiles = Arrays.asList(activeProfiles);
        List<String> activeProfileList = new ArrayList<>(profiles);
        Function<Object[], String> joinFun = StringUtils::arrayToCommaDelimitedString;
        SpringApplicationBuilder builder = new SpringApplicationBuilder(source);
        String profile;
        if (activeProfileList.isEmpty()) {
            profile = "dev";
            activeProfileList.add(profile);
            builder.profiles(profile);
        } else {
            if (activeProfileList.size() != 1) {
                throw new RuntimeException("同时存在环境变量:[" + StringUtils.arrayToCommaDelimitedString(activeProfiles) + "]");
            }
            profile = activeProfileList.get(0);
        }
        String activePros = joinFun.apply(activeProfileList.toArray());
        System.out.printf("----启动中，当前环境为:[%s]", activePros);
        Properties props = System.getProperties();
        // 加载通用配置项
        props.setProperty("spring.application.name", appName);
        props.setProperty("spring.profiles.active", profile);
        props.setProperty("file.encoding", StandardCharsets.UTF_8.name());
        // 加载nacos配置项
        props.setProperty("spring.cloud.nacos.discovery.server-addr", LauncherConstant.nacosAddr(profile));
        props.setProperty("spring.cloud.nacos.config.server-addr", LauncherConstant.nacosAddr(profile));
        props.setProperty("spring.cloud.nacos.config.username", "nacos");
        props.setProperty("spring.cloud.nacos.config.password", "nacos");
        props.setProperty("spring.cloud.nacos.discovery.username", "nacos");
        props.setProperty("spring.cloud.nacos.discovery.password", "nacos");
        props.setProperty("spring.cloud.nacos.config.file-extension", "yaml");
        props.setProperty("spring.cloud.nacos.config.shared-configs[0].data-id", LauncherConstant.sharedDataId());
        props.setProperty("spring.cloud.nacos.config.shared-configs[0].group", "DEFAULT_GROUP");
        props.setProperty("spring.cloud.nacos.config.shared-configs[0].refresh", "true");
        props.setProperty("spring.cloud.nacos.config.shared-configs[1].data-id", LauncherConstant.sharedDataId(profile));
        props.setProperty("spring.cloud.nacos.config.shared-configs[1].group", "DEFAULT_GROUP");
        props.setProperty("spring.cloud.nacos.config.shared-configs[1].refresh", "true");

        // TODO 加载seata配置


        return builder;
    }


}
